package com.dream.common.threadPool;

import com.dream.common.log.LogUtil;
import com.dream.common.task.ThreadTask;
import com.dream.common.thread.DreamThread;
import com.dream.common.thread.IThread;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 线程池实现
 *
 * @author : ChenYu
 * @Classname : DreamThreadPool
 * @Date : 2021/9/13 下午2:15
 */
public class DreamThreadPool implements IThreadPool {

    /**
     * 当前轮换索引
     */
    protected AtomicLong turnIndex;

    /**
     * 线程数目
     */
    protected int threadNum;
    /**
     * 池名称
     */
    protected String poolName;

    /**
     * 线程数组
     */
    private IThread[] threads;

    /**
     * 开始标记
     */
    private volatile boolean initFlat;

    /**
     * 启动标记
     */
    private volatile boolean running;

    public DreamThreadPool() {
        this.turnIndex = new AtomicLong(0);
    }

    @Override
    public synchronized boolean initPool(int poolSize) {
        return initPool(poolSize, true, DreamThreadPool.class.getSimpleName());
    }

    @Override
    public synchronized boolean initPool(int poolSize, String poolName) {
        return initPool(poolSize, true, poolName);
    }


    @Override
    public synchronized boolean initPool(int poolSize, boolean daemon, String poolName) {
        if (this.initFlat) {
            LogUtil.LOG_COMMON.info("重复初始化线程!!!!!!!!!!");
            return false;
        }
        this.initFlat = true;
        this.threadNum = poolSize;
        this.poolName = poolName;
        this.threads = new IThread[this.threadNum];
        for (int i = 0; i < this.threadNum; i++) {
            IThread thread = new DreamThread();
            this.threads[i] = thread;
            thread.setDaemon(daemon);
            thread.setName(poolName + "_" + i);
        }
        return true;
    }

    @Override
    public synchronized void startLoop() {
        start();
    }

    @Override
    public synchronized void start() {
        if (this.running) {
            LogUtil.LOG_COMMON.info("重复开始线程!!!!!!!!!!");
            return;
        }
        running = true;
        // 开启所有线程
        for (int i = 0; i < threadNum; i++) {
            threads[i].start();
        }
    }

    @Override
    public void close(boolean waitBreak) {
        if (this.running) {
            this.running = false;

            // 各个线程退出
            for (int i = 0; i < threadNum; i++) {
                try {
                    threads[i].close(waitBreak);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // 设置标记
            this.running = false;
        }
    }

    @Override
    public boolean addTask(ThreadTask task) {
        return addTask(task, -1, false);
    }

    @Override
    public boolean addTask(ThreadTask task, int threadIdx, boolean first) {
        if (running) {
            if (threadIdx < 0) {
                threadIdx = (int) (turnIndex.incrementAndGet() % threadNum);
            } else {
                threadIdx = threadIdx % threadNum;
            }

            if (threadIdx >= 0 && threadIdx < threadNum) {
                IThread thread = threads[threadIdx];
                if (first) {
                    return thread.insertTask(task);
                } else {
                    return thread.addTask(task);
                }
            }
        }
        return false;
    }
}
